using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx;
using HarmonyLib;
using Hearthstone;
using Hearthstone.Progression;
using PegasusLettuce;
using PegasusShared;
using PegasusUtil;
using UnityEngine;

namespace Mercenary
{
    public static class UtilsBattle
    {
        //对战
        public static int HandleBattle(int phaseID)
        {
            if (phaseID == 3) return 0;

            UtilsLog.Log("[状态] 对局进行中");
            if (phaseID == 0)
            {
                UtilsLog.Log("[对局中] 回合结束");
                InputManager.Get().DoEndTurnButton();
                return 0;
            }

            if (EndTurnButton.Get().m_ActorStateMgr.GetActiveStateType() ==
                ActorStateType.ENDTURN_NO_MORE_PLAYS)
            {
                UtilsLog.Log("[对局中] 点击结束按钮");
                InputManager.Get().DoEndTurnButton();
                return 0;
            }

            // 策略计算
            List<BattleTarget> battleTargets = UtilsStra.GetStrategy
                (UtilsGui.strategyConf.m_name).GetBattleTargets(GameState.Get().GetTurn(),
                UtilsCom.BuildTargetFromCards(ZoneMgr.Get().FindZoneOfType<ZonePlay>
                    (Player.Side.OPPOSING).GetCards(), Player.Side.OPPOSING),
                UtilsCom.BuildTargetFromCards(ZoneMgr.Get().FindZoneOfType<ZonePlay>
                    (Player.Side.FRIENDLY).GetCards(), Player.Side.FRIENDLY),
                UtilsCom.BuildTargetFromCards(ZoneMgr.Get().FindZoneOfType<ZoneGraveyard>
                    (Player.Side.OPPOSING).GetCards(), Player.Side.OPPOSING));
            Dictionary<int, BattleTarget> dict =
                battleTargets.FindAll((BattleTarget i) => i.m_skillId != -1).ToDictionary(
                    (BattleTarget i) => i.m_skillId, (BattleTarget i) => i);

            // 选择目标阶段
            if (GameState.Get().GetResponseMode() == GameState.ResponseMode.OPTION_TARGET)
            {
                foreach (BattleTarget battleTarget in battleTargets)
                {
                    UtilsLog.Log(string.Format("[对局中] 策略判断 [SID:{0}] [TID:{1}] [TTYPE:{2}]",
                        battleTarget.m_skillId, battleTarget.m_oppoTarId,
                        battleTarget.m_targetType));
                }

                List<Card> cards_opposite = UtilsCom.GetValidTargetPlayCard(Player.Side.OPPOSING);
                List<Card> cards_friend = UtilsCom.GetValidTargetPlayCard(Player.Side.FRIENDLY);

                //这个是当前停留的技能id
                Network.Options.Option.SubOption networkSubOption =
                    GameState.Get().GetSelectedNetworkSubOption();
                UtilsLog.Log(string.Format("[对局中] 技能目标 当前技能 [SID:{0}]",
                    networkSubOption.ID));

                //先
                Card card = null;
                if (dict.ContainsKey(networkSubOption.ID) &&
                    dict[networkSubOption.ID].m_oppoTarId != -1)
                {
                    UtilsLog.LogStra("[对局中] 技能目标 匹配策略"); 
                    if (dict[networkSubOption.ID].m_targetType == TargetType_E.Unspecified)
                    {
                        card = cards_opposite.Find(
                            (Card i) => i.GetEntity().GetEntityId() ==
                            dict[networkSubOption.ID].m_oppoTarId);
                        if (card == null)
                        {
                            card = cards_friend.Find(
                                (Card i) => i.GetEntity().GetEntityId() ==
                                dict[networkSubOption.ID].m_oppoTarId);
                        }
                    }
                    else if (dict[networkSubOption.ID].m_targetType == TargetType_E.Friendly)
                    {
                        card = cards_friend.Find(
                            (Card i) => i.GetEntity().GetEntityId() ==
                            dict[networkSubOption.ID].m_oppoTarId);
                    }
                }

                if (card == null && cards_opposite.Count != 0)
                {
                    UtilsLog.Log("[对局中] 技能目标 敌方首位");
                    card = cards_opposite[0];
                }
                if (card == null && cards_friend.Count != 0)
                {
                    UtilsLog.Log("[对局中] 技能目标 友方首位");
                    card = cards_friend[0];
                }
                if (card == null)
                {
                    UtilsLog.Log("[对局中] 技能目标 无可用目标 过");
                    InputManager.Get().DoEndTurnButton();
                }

                Traverse.Create(InputManager.Get()).Method("DoNetworkOptionTarget",
                    new object[]{card.GetEntity()}).GetValue();
            }

            //操作
            if (GameState.Get().GetResponseMode() == GameState.ResponseMode.OPTION)
            {
                ZonePlay zonePlay = ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.FRIENDLY);

                //特殊处理
                if(UtilsGui.autoConcede && UtilsGui.modeConf.m_id == UiItemConst.模式_真人PVP.m_id)
                {
                    GameState.Get().Concede();
                    UtilsLog.LogStra("[配置] Pvp自动投降");
                    return 0;
                }
                if (UtilsGui.modeConf.m_id == UiItemConst.模式_挂机收菜.m_id)
                {
                    if(UtilsGui.readyToHang)
                    {
                        int time = UtilsGui.pveInterval;
                        if (UtilsLog.WriteAwakeTime(time))
                        {
                            UtilsLog.Log(string.Format(
                                "[战斗中] 初次进入战斗，休息{0}分{1}秒后再见~", time / 60, time % 60));
                            Application.Quit();
                        }
                        else 
                        {
                            UtilsLog.Log(string.Format("[战斗中] 收菜时间写入失败，稍后再试~"));
                            return 0;
                        }
                    }
                    if(!UtilsGui.needToHang)
                    {
                        GameState.Get().Concede();
                        UtilsLog.LogStra("[收菜] 收菜时间截至，自动投降");
                        return 0;
                    }
                }

                //选择佣兵上场
                if (phaseID == 1 && EndTurnButton.Get().m_ActorStateMgr.GetActiveStateType() ==
                    ActorStateType.ENDTURN_YOUR_TURN)
                {
                    ZoneHand zoneHand = ZoneMgr.Get().FindZoneOfType<ZoneHand>(Player.Side.FRIENDLY);
                    if (zoneHand != null)
                    {
                        (int hand_index, int play_index) = UtilsStra.GetStrategy(
                            UtilsGui.strategyConf.m_name).GetEnterOrder(
                            UtilsCom.BuildMercFromCard(zoneHand.GetCards()),
                            UtilsCom.BuildMercFromCard(zonePlay.GetCards()));

                        GameState gameState = GameState.Get();
                        if (gameState != null)
                        {
                            UtilsLog.LogStra(string.Format("[佣兵登场] 选择[佣兵{0}:{1}]，位置[{2}]",
                                hand_index,zoneHand.GetCardAtIndex(hand_index).
                                GetEntity().GetName(),play_index));
                            gameState.SetSelectedOption(hand_index + 1);
                            gameState.SetSelectedSubOption(-1);
                            gameState.SetSelectedOptionTarget(0);
                            gameState.SetSelectedOptionPosition(play_index + 1);
                            gameState.SendOption();
                            Main.Sleep(UtilsGui.pvpDelayTime);
                            UtilsLog.LogStra(string.Format("[佣兵上场等待] 剩余时间:{0}秒",
                                UtilsGui.pvpDelayTime));
                        }
                        return 0;
                    }
                }

                if (phaseID == 2)
                {
                    ZonePlay zonePlay2 = ZoneMgr.Get().FindZoneOfType<ZonePlay>(
                        Player.Side.OPPOSING);
                    UtilsInfo.MercRecord(zonePlay2);
                    if (zonePlay2.GetCardCount() == 1 &&
                        zonePlay2.GetFirstCard().GetEntity().IsStealthed())
                    {
                        UtilsLog.LogStra("对面隐身，结束回合");
                        InputManager.Get().DoEndTurnButton();
                        return 0;
                    }

                    if (ZoneMgr.Get().GetLettuceAbilitiesSourceEntity() == null)
                    {
                        using (List<Card>.Enumerator enumerator2 =
                            zonePlay.GetCards().GetEnumerator())
                        {
                            while (enumerator2.MoveNext())
                            {
                                Card card2 = enumerator2.Current;
                                Entity entity = card2.GetEntity();
                                if (!entity.HasSelectedLettuceAbility() ||
                                    !entity.HasTag(GAME_TAG.LETTUCE_HAS_MANUALLY_SELECTED_ABILITY))
                                {
                                    ZoneMgr.Get().DisplayLettuceAbilitiesForEntity(entity);
                                    return 1;
                                }
                            }
                            //抉择技能
                            if (GameState.Get().GetResponseMode() ==
                                GameState.ResponseMode.SUB_OPTION)
                            {
                                List<Card> friendlyCards = ChoiceCardMgr.Get().GetFriendlyCards();
                                int skill_id = ChoiceCardMgr.Get().
                                    GetSubOptionParentCard().GetEntity().GetEntityId();
                                int subskill_index = friendlyCards.Count - 1;
                                if (dict.ContainsKey(skill_id) && dict[skill_id].m_subSkillId != -1)
                                {
                                    subskill_index = dict[skill_id].m_subSkillId;
                                }
                                UtilsLog.LogStra("[对局中] 技能选择 使用抉择技能index:" +
                                    subskill_index.ToString());
                                InputManager.Get().HandleClickOnSubOption(
                                    friendlyCards[subskill_index].GetEntity(),false);
                                return 1;
                            }
                            return 0;
                        }
                    }

                    ZonePlay zonePlay_friendly = ZoneMgr.Get().FindZoneOfType<ZonePlay>(
                        Player.Side.FRIENDLY);
                    Entity currentSelectMerc_Entity =
                        ZoneMgr.Get().GetLettuceAbilitiesSourceEntity();
                    BattleTarget currentMerc_BattleTarget =
                        battleTargets.Find((BattleTarget i) => i.m_frieTarName ==
                            currentSelectMerc_Entity.GetName());
                    // 策略规定此佣兵可以操作
                    if (currentMerc_BattleTarget == null ||
                        currentMerc_BattleTarget.m_bAllowOption == true)
                    {
                        UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 开始技能选择[{0}]",
                            currentSelectMerc_Entity.GetName()));

                        Card card = null;
                        List<Card> displayedLettuceAbilityCards =
                            ZoneMgr.Get().GetLettuceZoneController().
                            GetDisplayedLettuceAbilityCards();

                        foreach (BattleTarget batterTarget in battleTargets)
                        {
                            card = displayedLettuceAbilityCards.Find(
                                (Card i) => i.GetEntity().GetEntityId() ==
                                batterTarget.m_skillId && GameState.Get().HasResponse(
                                    i.GetEntity(), new bool?(false)));
                            if (card != null) break;
                        }

                        if (card != null)
                        {
                            UtilsLog.LogStra(string.Format("[对局中] 技能选择 匹配策略[{0}]",
                                card.GetEntity().GetName()));
                        }
                        else
                        {
                            card = displayedLettuceAbilityCards.Find(
                                (Card i) => GameState.Get().HasResponse(i.GetEntity(),
                                new bool?(false)));
                            UtilsLog.LogStra(string.Format("[对局中] 技能选择 顺序选择[{0}]",
                                card.GetEntity().GetName()));
                        }
                        Traverse.Create(InputManager.Get()).Method("HandleClickOnCardInBattlefield",
                            new object[]{card.GetEntity(),true}).GetValue();
                        return 1;
                    }
                    else
                    {
                        //策略规定此佣兵不可以操作
                        UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 设置为不操作[{0}]",
                            currentSelectMerc_Entity.GetName()));
                        Dictionary<string, bool> dict_mercactive = new Dictionary<string, bool>();
                        foreach (BattleTarget battleTarget in battleTargets)
                        {
                            if (battleTarget.m_frieTarName.Length <= 0) continue;
                            if (!dict_mercactive.ContainsKey(battleTarget.m_frieTarName))
                            {
                                dict_mercactive.Add(battleTarget.m_frieTarName,
                                    battleTarget.m_bAllowOption);
                            }
                        }
                        bool result = false;
                        Card nextSelectMerc_Card = zonePlay_friendly.GetCards().Find(
                            (Card i) => (!i.GetEntity().HasSelectedLettuceAbility() ||
                            !i.GetEntity().HasTag(GAME_TAG.LETTUCE_HAS_MANUALLY_SELECTED_ABILITY))
                            && (false == dict_mercactive.TryGetValue(
                            i.GetEntity().GetName(), out result) || result == true));
                        if (nextSelectMerc_Card != null)
                        {
                            UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 手动选择下一个佣兵[{0}]",
                                nextSelectMerc_Card.GetEntity().GetName()));
                            ZoneMgr.Get().DisplayLettuceAbilitiesForEntity(
                                nextSelectMerc_Card.GetEntity());
                            return 1;
                        }
                        else
                        {
                            UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 无可操作佣兵 结束回合"));
                            InputManager.Get().DoEndTurnButton();
                            return 1;
                        }
                    }
                }
            }

            return 0;
        }
    }
}